﻿/*              Copyright(c) 2008 Dave Sexton              *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace DaveSexton.DocToMaml
{
	internal enum ExitCode
	{
		Success = 0,
		ShowUsage = -1, 
		InvalidSwitch = -2,
		DuplicateSwitch = -3,
		MissingProject = -4
	}

	internal sealed class ProgramArguments
	{
		#region Public Properties
		public bool Convert
		{
			get
			{
				return convert ?? false;
			}
		}

		public bool Unattended
		{
			get
			{
				return unattended ?? false;
			}
		}

		public bool CanAttachToParent
		{
			get
			{
				return canAttachToParent ?? false;
			}
		}

		public string Project
		{
			get
			{
				return project;
			}
		}

		public ExitCode ExitCode { get; private set; }
		#endregion

		#region Private / Protected
		private bool? convert, unattended, canAttachToParent;
		private string project;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ProgramArguments" /> class.
		/// </summary>
		public ProgramArguments()
		{
		}
		#endregion

		#region Methods
		public void Load(string[] args)
		{
			convert = null;
			unattended = null;
			project = null;

			if (args != null && args.Length > 0)
			{
				foreach (string arg in args)
				{
					if (arg.StartsWith("-", StringComparison.Ordinal) || arg.StartsWith("/", StringComparison.Ordinal))
					{
						string value = arg.Substring(1);

						try
						{
							if (IsArgument(value, canAttachToParent, "attach", "a"))
								canAttachToParent = true;
							else if (IsArgument(value, convert, "convert", "c"))
								convert = true;
							else if (IsArgument(value, unattended, "unattended", "u"))
								unattended = true;
							else if (IsArgument(value, (string) null, "help", "?"))
							{
								ExitCode = ExitCode.ShowUsage;
								return;
							}
							else
							{
								ExitCode = ExitCode.InvalidSwitch;
								return;
							}
						}
						catch (ArgumentException)
						{
							return;
						}
					}
					else
						project = arg;
				}
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
		private bool IsArgument<T>(string arg, T currentValue, params string[] names)
		{
			bool isDefault = (default(T) == null && ((object) currentValue) == null)
				|| currentValue.Equals(default(T));

			foreach (string name in names)
			{
				if (string.Equals(arg, name, StringComparison.OrdinalIgnoreCase))
				{
					if (isDefault)
						return true;
					else
					{
						ExitCode = ExitCode.DuplicateSwitch;
						throw new ArgumentException();
					}
				}
			}

			return false;
		}
		#endregion
	}
}
